﻿using Cloo;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace SimpleCLML
{
    /// <summary>
    /// takes care of setting up / disposing things
    /// </summary>
    public abstract class OpenCLAlgorithmBase : IDisposable
    {
        protected ComputeContext context;

        protected OpenCLAlgorithmBase()
        {            
            // TODO: allow selection
            ComputePlatform platform = ComputePlatform.Platforms[0];
            ComputeContextPropertyList properties = new ComputeContextPropertyList(platform);
            context = new ComputeContext(platform.QueryDevices().ToList(), properties, null, IntPtr.Zero);
        }
        
        /// <summary>
        /// Loads CL program from resource, replaces %{key}% strings with values and builds it
        /// </summary>
        /// <param name="programName">resource name</param>
        /// <param name="values" optional="true">Key value pairs to change %key% tokens in CL program text</param>
        /// <returns>ComputeProgram</returns>
        protected ComputeProgram LoadProgramFromResources(string programName, IDictionary<string,object> values=null)
        {
            using (var rdr = new StreamReader(Assembly.GetCallingAssembly().GetManifestResourceStream(programName)))
            {
                string template = rdr.ReadToEnd();
                string text = values == null ? template : values.Aggregate(template, (a, kv) => a.Replace(String.Format("%{0}%", kv.Key), kv.Value.ToString()));                
                var prg = new ComputeProgram(context, text);
                prg.Build(null, null, null, IntPtr.Zero);
                return prg;
            }
        }

        protected abstract void OnDisposing();

        public void Dispose()
        {
            OnDisposing();
            if (context != null)
            {
                context.Dispose();
            }
        }
    }
}
